package com.zds.scm.common;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class CommonServlet extends HttpServlet {

	public static final Logger logger = Logger.getLogger(CommonServlet.class);
    private int currentPage=-1; //当前页
    private int pageSize=10;   //每页,分页大小固定大小为10页
	private static final long serialVersionUID = 7250105925144730223L;
	
	protected HashMap<String,Method> methods = new HashMap<String,Method>();
	protected Class<?> clazz = this.getClass();
	protected Class<?>[] types ={HttpServletRequest.class,HttpServletResponse.class};
	
	public CommonServlet() {
		super();
		logger.debug("通用Servlet构造");
	}
	public void destroy() {
		logger.debug("通用servlet销毁");
		super.destroy(); 
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		logger.debug("通用servlet执行doGet");
		doPost(request, response);
	}
	public  void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		logger.debug("通用servlet执行doPost");
		String command=request.getParameter("command");
		//如果传了分页参数的话，那么此处需要提取分页参数
		 try {
		   	currentPage=Integer.parseInt(request.getParameter("pageNum"));
		    pageSize=Integer.parseInt(request.getParameter("numPerPage"));
		} catch (Exception e) {
			currentPage=1;
			pageSize=10;
		}
		request.setAttribute("currentPage", currentPage);
		request.setAttribute("numPerPage", pageSize);
		
		//解析命令		
		logger.debug("通用servlet执行doPost。解析命令:command="+command);
		if("doPost".equals(command)||"doGet".equals(command)||"".equals(command)||command==null){
			logger.error("命令错误");
			response.sendError(500, "命令错误,调用servlet时必须带参数command");
		}else {
			Object[] args = {request, response}; //参数
			try {
				Method method = getMethod(command);
				method.invoke(this, args);
			} catch (NoSuchMethodException e) {
				logger.error(this.getServletName()+"中没有如此名字的方法:"+command);
				response.sendError(500,"名字为:"+this.getServletName()+"的Servlet中没有签名为:public void "+command+"(HttpServletRequest request, HttpServletResponse response)方法");
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				logger.error("方法参数异常:command="+command);
				response.sendError(500,command+":方法参数异常,应该和doPost参数一致");
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				logger.error("方法存取异常:command="+command);
				response.sendError(500,"方法存取异常:command="+command);
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				logger.error("在目标上执行方法异常:command="+command);
				response.sendError(500,"在目标上执行方法异常:command="+command);
				e.printStackTrace();
			} catch (Exception e) {
				logger.error("执行方法异常:"+command);
				response.sendError(500,"执行方法异常:"+command);
				e.printStackTrace();
			}
		}
	}
	public void init() throws ServletException {
		logger.debug("通用Servlet初始化");
	}
	/**
	 * 从方法列表中找参数传递过来的方法，如果没找到
	 * 则根据指定的参数和名字构造一个方法,并返回
	 * @param name
	 * @return
	 * @throws NoSuchMethodException
	 */
	protected Method getMethod(String name)  throws NoSuchMethodException {
		
      synchronized (methods) {
        Method method = (Method) methods.get(name);

        if (method == null) {
            method = clazz.getMethod(name, types); //在本类上找到叫这个名字的，并且参数为指定参数的方法
            methods.put(name, method);
        }
        return (method);
    }
}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
}
